
#ifndef _E_APP_H_
#define _E_APP_H_

#include <OgreConfigFile.h>
#include "EFrameListener.h"
#include "eH.h"

#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
#include <CoreFoundation/CoreFoundation.h>

// This function will locate the path to our application on OS X,
// unlike windows you can not rely on the curent working directory
// for locating your configuration files and resources.
std::string macBundlePath()
{
    char path[1024];
    CFBundleRef mainBundle = CFBundleGetMainBundle();
    assert(mainBundle);

    CFURLRef mainBundleURL = CFBundleCopyBundleURL(mainBundle);
    assert(mainBundleURL);

    CFStringRef cfStringRef = CFURLCopyFileSystemPath( mainBundleURL, kCFURLPOSIXPathStyle);
    assert(cfStringRef);

    CFStringGetCString(cfStringRef, path, 1024, kCFStringEncodingASCII);

    CFRelease(mainBundleURL);
    CFRelease(cfStringRef);

    return std::string(path);
}

#endif

namespace engine {

/** Base class which manages the standard startup of an Ogre application.
    Designed to be subclassed for specific examples if required.
*/
class EApp
{
  static const string     s_sOgreCfgFileName;
  static const string     s_sOgreLogFileName;
  static const string     s_sOgrePluginsCfgFileName;
  static const string     s_sOgreResourcesCfgFileName;
public:
  EApp();

  /// Standard destructor
  virtual ~EApp();

  /// Start the example
  virtual bool go( void );

  AnimationState          *m_pAnimationState;
  Camera*                 m_pCamera;

protected:

  // These internal methods package up the stages in the startup process
  /** Sets up the application - returns false if the user chooses to abandon configuration. */
  virtual bool setup(void);
  /** Configures the application - returns false if the user chooses to abandon configuration. */
  virtual bool configure(void);
  virtual void chooseSceneManager(void);
  virtual void createCamera(void);
  virtual void createFrameListener(void);
  virtual bool createScene(void) = 0;    // pure virtual - this has to be overridden
  virtual void updateScene(){}
  virtual void destroyScene(void){}    // Optional to override this
  virtual void createViewports(void);
  /// Method which will define the source of resources (other than current folder)
  virtual void setupResources(void);
	/// Optional override method where you can create resource listeners (e.g. for loading screens)
	virtual void createResourceListener(void){}

	/// Optional override method where you can perform resource group loading
	/// Must at least do ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
	virtual void loadResources(void);

  Root*                   m_pRoot;
  
  SceneManager*           m_pSceneManager;
  EFrameListener*         m_pFrameListener;
  RenderWindow*           mWindow;
  Ogre::String            m_pResourcePath;
};

} // end namespace

#endif
